package com.example.speeddating.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.speeddating.common.BaseResponse;
import com.example.speeddating.common.RespGenerator;
import com.example.speeddating.config.TokenBlacklistService;
import com.example.speeddating.constants.TaoHuaConstant;
import com.example.speeddating.constants.WeixinConstant;
import com.example.speeddating.entity.AutheticInfo;
import com.example.speeddating.entity.FriFolFan;
import com.example.speeddating.entity.TokenEntity;
import com.example.speeddating.entity.User;
import com.example.speeddating.exception.CommonException;
import com.example.speeddating.annotaion.LoginUser;
import com.example.speeddating.annotaion.TokenCheck;
import com.example.speeddating.enums.ResponseCodeEnum;
import com.example.speeddating.netty.CoordinationSocketHandler;
import com.example.speeddating.service.*;
import com.example.speeddating.tool.StringTools;
import com.example.speeddating.tool.WebTools;
import com.example.speeddating.utils.JwtConstant;
import com.example.speeddating.utils.JwtTokenUtil;
import com.example.speeddating.utils.SecretUtil;
import com.example.speeddating.utils.urlSaveImage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;

/**
 *
 * @author tina
 * @since 2023-06-28 11:14:34
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private TokenBlacklistService tokenBlacklistService;

    @Autowired
    private EmailCodeService emailCodeService;

    @Autowired
    private UserService userService;

    @Autowired
    private VisitorService visitorService;

    @Autowired
    private FollowService followService;

    @Autowired
    private TaohuaDetailService taohuaDetailService;

    @Autowired
    private MatchService matchService;

    @Autowired
    private CoordinationSocketHandler coordinationSocketHandler;

    @Autowired
    private urlSaveImage urlSaveImage;

    @PostMapping("/register")
    public BaseResponse reisterByEmail(@RequestBody HashMap<String,Object> jsonString) {
        log.info("logindto:{}",jsonString.toString());
        String email = jsonString.get("email").toString();
        String password = jsonString.get("password").toString();
        String emailCode = jsonString.get("code").toString();
        if (StringTools.isEmpty(email)||StringTools.isEmpty(password)||StringTools.isEmpty(emailCode)){
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        User user = userService.registerByEmail(email, emailCode, password);
        user.setFirstInit(true);
        user.setIsOnline(true);
        userService.updateUser(user);
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConstant.USER_INFO_ID, user.getId());
        claims.put(JwtConstant.USER_INFO_USERNAME, user.getNickname());
        claims.put(JwtConstant.JWT_CREATE_TIME, new Date());
        String token = JwtTokenUtil.createToken(claims);
        HashMap<String, Object> map = new HashMap<>();
        map.put("user",user);
        map.put("token",token);
        return RespGenerator.returnOK(map);
    }

    @TokenCheck(roles = "user")
    @RequestMapping("/sendEmailCode")
    public BaseResponse sendEmailCode(@LoginUser TokenEntity tokenEntity, String email, Integer type) {
        log.info("sendEmailCode");
        if (StringTools.isEmpty(email)||type==null) {
            log.info("请求参数错误");
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        emailCodeService.sendEmailCode(email,type);
        return RespGenerator.returnOK(null);
    }

    /**
     * 用户登录
     * @param code
     * @param jsonString
     * @return
     */
    @PostMapping("/login")
    public BaseResponse login(@RequestParam(value = "code") String code, @RequestBody HashMap<String,Object> jsonString) throws IOException {

        // 向微信服务器发送请求，获取access_token和openid等信息
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+ WeixinConstant.appid +"&secret="+WeixinConstant.secret+"&js_code=" + code + "&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
        String responseBody = response.getBody();
        JSONObject jsonObject = JSON.parseObject(responseBody);
        String openid = jsonObject.getString("openid");

//      查询数据库看是否注册过
        User user = userService.selectByUserOpenid(openid);
        if (user!=null&&user.getDeleted()==1){
            //  判断是否注销或禁用用户
            throw new CommonException(ResponseCodeEnum.CODE_604);
        }
        if (user == null) {
//             把openid存入数据层
            User newUser = new User();
            newUser.setOpenid(openid);
            newUser.setNickname(jsonString.get("nickname").toString());
            newUser.setSex(Byte.valueOf(jsonString.get("sex").toString()));
            String temp = "avator/"+UUID.randomUUID();
            urlSaveImage.saveImage(jsonString.get("avator").toString(), temp);
            newUser.setAvator(temp);
            newUser.setLastLoginTime(new Date());
            newUser.setIsOnline(true);
            newUser = userService.insert(newUser);
            taohuaDetailService.insertTaohuaDetail(TaoHuaConstant.Type_1,newUser.getId());
            newUser.setFirstInit(true);
            user = newUser;
        }else {
            if (user.getStatus()==0){
                throw new CommonException(ResponseCodeEnum.CODE_605);
            }
            user.setFirstInit(false);
        }
        //更新登录时间与上线
        user.setLastLoginTime(new Date());
        user.setIsOnline(true);
        userService.updateUser(user);

//        生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConstant.USER_INFO_ID, user.getId());
        claims.put(JwtConstant.USER_INFO_USERNAME, user.getNickname());
        claims.put(JwtConstant.JWT_CREATE_TIME, new Date());
        String token = JwtTokenUtil.createToken(claims);
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", token);
        return RespGenerator.returnOK(map);
    }

    /**
     * 用户退出
     * @param tokenEntity
     * @return
     */
    @PostMapping("/logout")
    @TokenCheck(roles = "user")
    public BaseResponse logout(@LoginUser TokenEntity tokenEntity){
        coordinationSocketHandler.websocketLogout(tokenEntity.getId());
        User user = new User();
        user.setLastLoginTime(new Date());
        user.setId(tokenEntity.getId());
        user.setIsOnline(false);
        userService.updateUser(user);
        return RespGenerator.returnOK("退出成功");
    }

    /**
     * 用户登录
     * @param jsonString
     * @param jsonString
     * @return
     */
    @PostMapping("/login_email")
    public BaseResponse loginByEmail(@RequestBody HashMap<String,Object> jsonString) {
        String email = jsonString.get("email").toString();
        String password = jsonString.get("password").toString();
        User user = userService.loginByEmail(email, SecretUtil.encrypt(password));
//        //  判断是否注销或禁用用户
        if (user.getDeleted()==1){
            throw new CommonException(ResponseCodeEnum.CODE_604);
        }
        if (user.getStatus()==0){
            throw new CommonException(ResponseCodeEnum.CODE_605);
        }
        user.setIsOnline(true);
        user.setLastLoginTime(new Date());
        user.setIsOnline(true);
        userService.updateUser(user);
//        生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConstant.USER_INFO_ID, user.getId());
        claims.put(JwtConstant.USER_INFO_USERNAME, user.getNickname());
        claims.put(JwtConstant.JWT_CREATE_TIME, new Date());
        String token = JwtTokenUtil.createToken(claims);
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", token);
        return RespGenerator.returnOK(map);
    }


    /**
     * 登录过 加载用户信息
     * @return user
     * @author tina
     */
    @TokenCheck(roles = "user")
    @PostMapping("/load")
    public BaseResponse loadUser(@LoginUser TokenEntity tokenEntity){
        Long userId = tokenEntity.getId();
        User user = userService.selectByUserId(userId);
        user.setIsOnline(true);
        user.setLastLoginTime(new Date());
        user.setIsOnline(true);
        userService.updateUser(user);
        return RespGenerator.returnOK(user);
    }

    /**
     * 好友列表
     */
    @TokenCheck(roles = "user")
    @RequestMapping("/friends_list")
    public BaseResponse<Page> friendList(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return RespGenerator.returnOK(userService.selectFriendList(page,tokenEntity.getId()));
    }

    /**
     * 关注列表
     */
    @TokenCheck(roles = "user")
    @RequestMapping("/follow_list")
    public BaseResponse<Page> followList(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return RespGenerator.returnOK(userService.selectFollowList(page,tokenEntity.getId()));
    }

    /**
     * 粉丝列表
     */
    @TokenCheck(roles = "user")
    @RequestMapping("/fans_list")
    public BaseResponse<FriFolFan> fansList(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return RespGenerator.returnOK(userService.selectFansList(page,tokenEntity.getId()));
    }

    /**
     * 访客列表
     */
    @TokenCheck(roles = "user")
    @RequestMapping("/seenme_list")
    public BaseResponse<FriFolFan> seenmeList(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return RespGenerator.returnOK(userService.seenMeList(page,tokenEntity.getId()));
    }

    /**
     * 更新已读访客
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/update_visitors")
    public BaseResponse updateVisitor(@LoginUser TokenEntity tokenEntity){
        Long userId = tokenEntity.getId();
        visitorService.batchUpdateVistors(userId);
        return RespGenerator.returnOK(null);
    }

    /**
     * 更新已读粉丝
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/update_fans")
    public BaseResponse updateFollow(@LoginUser TokenEntity tokenEntity){
        Long userId = tokenEntity.getId();
        followService.batchupdateFollow(userId);
        return RespGenerator.returnOK(null);
    }

    /**
     * seeother列表
     */
    @TokenCheck(roles = "user")
    @RequestMapping("/seenother_list")
    public BaseResponse<FriFolFan> seenotherList(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return RespGenerator.returnOK(userService.seenOtherList(page,tokenEntity.getId()));
    }

    /**
     * 查询用户
     */
    @TokenCheck(roles = "user")
    @GetMapping("/select/{id}")
    public BaseResponse<User> selectUser(@LoginUser TokenEntity tokenEntity,@PathVariable Long id) {
        return RespGenerator.returnOK(userService.selectByUserId(id,tokenEntity.getId()));
    }

    /**
     * 更新用户信息
     * @param jsonString
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/update")
    public BaseResponse<User> updateUser(@LoginUser TokenEntity tokenEntity,@RequestBody HashMap<String,Object> jsonString) throws Exception {

        Long id = tokenEntity.getId();
        User user = userService.selectByUserId(id);
        if (user==null){
            throw new CommonException("用户不存在");
        }
        user.setNickname(jsonString.get("nickname").toString());
        if (jsonString.get("constellation")!=null){
           user.setConstellation(jsonString.get("constellation").toString());
        }
        if (jsonString.get("birthday")!=null){
            user.setBirthday(WebTools.StringToDate(jsonString.get("birthday").toString()));
        }
        if(jsonString.get("introduce")!=null){
            user.setIntroduce(jsonString.get("introduce").toString());
        }
        if (jsonString.get("height")!=null){
            user.setHeight(Integer.parseInt(jsonString.get("height").toString()));
        }
        if (jsonString.get("location")!=null){
            user.setLocation(jsonString.get("location").toString());
        }
        if (jsonString.get("profession_id")!=null){
            user.setProfessionId(Integer.parseInt(jsonString.get("profession_id").toString()));
        }
        if (jsonString.get("school")!=null){
            user.setSchool(jsonString.get("school").toString());
        }
        if (jsonString.get("education")!=null){
            user.setEducation(jsonString.get("education").toString());
        }
        if (user.getLocation()!=null&&user.getIntroduce()!=null&&user.getHeight()!=0&&user.getConstellation()!=null&&user.getProfessionId()!=null&&user.getSchool()!=null&&user.getEducation()!=null){
            user.setIsComplete(true);
        }
        userService.updateUser(user);
        return RespGenerator.returnOK(user);
    }


    /**
     * 初始化用户信息
     * @param jsonString
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/init")
    public BaseResponse<User> initUser(@LoginUser TokenEntity tokenEntity,@RequestBody HashMap<String,Object> jsonString) throws Exception {
        Long id = tokenEntity.getId();
        log.info(id+"");
        User user = userService.selectByUserId(id);
        if (user==null){
            throw new CommonException("用户不存在");
        }
        user.setSex(Byte.valueOf(jsonString.get("sex").toString()));
        user.setLocation(jsonString.get("location").toString());
        user.setConstellation(jsonString.get("constellation").toString());
        user.setBirthday(WebTools.StringToDate(jsonString.get("birthday").toString()));
        System.out.println(user.toString());
        userService.updateUser(user);
        return RespGenerator.returnOK(user);
    }


    /**
     * 查询每日信息
     * @param
     * @return
     */
    @TokenCheck(roles = "user")
    @GetMapping("/task")
    public BaseResponse everydayTask(@LoginUser TokenEntity tokenEntity) throws Exception {
        HashMap<String,Boolean> map  = userService.selectEverydayTask(tokenEntity.getId());
        return RespGenerator.returnOK(map);
    }

    /**
     * 得到用户点赞评论提醒
     * @param tokenEntity
     * @param pageNum
     * @param pageSize
     * @return
     */
    @TokenCheck(roles = "user")
    @GetMapping("/reaction")
    public BaseResponse<Page> reaction(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "5") int pageSize){
        return RespGenerator.returnOK(userService.getUserCommentLikeData(tokenEntity.getId(),pageNum,pageSize));
    }

    @TokenCheck(roles = "user")
    @GetMapping("/update/reaction")
    public BaseResponse<Page> updateReaction(@LoginUser TokenEntity tokenEntity){
        userService.updateReaction(tokenEntity.getId());
        return RespGenerator.returnOK("更新成功");
    }




    /**
     * 匹配信息
     * @param tokenEntity
     * @param pageNum
     * @param pageSize
     * @return
     */
    @TokenCheck(roles = "user")
    @GetMapping("/match_user")
    public BaseResponse<Page> getMatchUser(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize){
        return RespGenerator.returnOK(matchService.selectMatchUser(pageNum,pageSize,tokenEntity.getId()));
    }


    /**
     * 关注信息
     * @param tokenEntity
     * @param pageNum
     * @param pageSize
     * @return
     */
    @TokenCheck(roles = "user")
    @GetMapping("/follow_user")
    public BaseResponse<Page> getFollowedUser(@LoginUser TokenEntity tokenEntity,@RequestParam(value = "pageNum",defaultValue = "1") int pageNum , @RequestParam(value = "pageSize",defaultValue = "10") int pageSize){
        return RespGenerator.returnOK(followService.selectFollowUser(pageNum,pageSize,tokenEntity.getId()));
    }

    @GetMapping("/test")
    public BaseResponse<List<User>> getSilimarUser(){
        return RespGenerator.returnOK(userService.getSimilarUser(1,10,10014L,4));
    }

    /**
     * 更改提示状态
     * @param tokenEntity
     * @param jsonString
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/update/notice")
    public BaseResponse updateNotice(@LoginUser TokenEntity tokenEntity,@RequestBody HashMap<String,Object> jsonString){
        if (jsonString.get("noticeType")==null){
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        Integer noticeType = Integer.valueOf(jsonString.get("noticeType").toString());
        if (!noticeType.equals(0)&&!noticeType.equals(1)){
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        userService.updateNotice(tokenEntity.getId(),noticeType);
        return RespGenerator.returnOK("更改成功");
    }

    /**
     * 隐身0（默认） 1
     * @param tokenEntity
     * @param jsonString
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/update/hide")
    public BaseResponse updateHide(@LoginUser TokenEntity tokenEntity,@RequestBody HashMap<String,Object> jsonString){
        if (jsonString.get("hideType")==null){
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        Integer hideType = Integer.valueOf(jsonString.get("hideType").toString());
        if (!hideType.equals(0)&&!hideType.equals(1)){
            throw new CommonException(ResponseCodeEnum.CODE_600);
        }
        userService.updateHide(tokenEntity.getId(),hideType);
        return RespGenerator.returnOK("更改成功");
    }

    /**
     * 注销成功
     * @param tokenEntity
     * @return
     */
    @TokenCheck(roles = "user")
    @PostMapping("/logoff")
    public BaseResponse logOff(@LoginUser TokenEntity tokenEntity){
        userService.logOff(tokenEntity.getId());
        return RespGenerator.returnOK("注销成功");
    }


}
